function varargout = TLLookup2DDlg(action,varargin)

% TL_LOOKUP2D_DLG manages the user interface for TargetLink Look-Up Table 2D block
%
% SYNTAX dlgInfo = TLLookup2dDlg('GetDlgInfo');
%   gets dialog info of TargetLink Look-Up Table 2D block
%
%   INPUT ARGUMENTS
%   -/-
%
%   OUTPUT ARGUMENTS
%   dlgInfo     dialog information contains pageNames etc.
%
% SYNTAX [sheetDims, ctrlPos] = TLLookup2dDlg('CtrlPositions', pageName, commonGeom, dlgInfo, sheetDims);
%   calculates the control positions of all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   commonGeom      common geometry data
%   dlgInfo         dialog information contains pageNames etc.
%   sheetDims       dimension of sheet
%
%   OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% SYNTAX dlgdata = TLLookup2dDlg('Create', pageName, dlgfig, dlgdata);
%   creates all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX [dlgdata,bModified] = TLLookup2dDlg('Manage', pageName, dlgfig, dlgdata, pageAction);
%   manages all actions of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageAction      modified control of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%
% SYNTAX dlgdata = TLLookup2dDlg('Update', dlgfig, dlgdata, pageNum);
%   updates all controls of dialog page: <pageNum>
%
%   INPUT ARGUMENTS
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageNum         number of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX TLLookup2dDlg('Apply', dlgfig, dlgdata);
%   writes current blockdata to block and DD
%
%   INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
%   OUTPUT ARGUMENTS
%   - / -


% Author(s): D. Andoleit, T. Pietzsch
% $RCSfile: TLLookup2dDlg.m $
% $ProjectName: e:/ARC/Components/HostSW/SimulinkBlocksets/TLBlocksets/CommonBlockset/CommonBlockset_SimBlocksUI/Sources/MSrc/project.pj $
% $Revision: 1.29 $
% $Date: 2011/09/02 08:53:19MESZ $
%
% Copyright ?2011 dSPACE GmbH. All rights reserved.


switch action
    
    case 'GetDlgInfo'
        hBlock = varargin{1};
        dlgInfo = tl_get_dlginfodefaults('tlsim');
        titleName = 'Look-Up Table (2D)';
        pathinfo = tl_pathinfo(hBlock);
        dlgInfo.title = sprintf('TargetLink %s: %s', titleName, pathinfo.shortDisplayName);
        dlgInfo.pageNames   = {
            'General';
            'Output';
            'Table';
            'Axis#1';
            'Axis#2';
            'Map';
            'Logging & Autoscaling';
            'Documentation'};
        varargout{1} = dlgInfo;
        varargout{2} = get_tlcg_data(hBlock);
        
    case 'CtrlPositions'
        pageName     = varargin{1};
        commonGeom   = varargin{2};
        sheetDims    = varargin{4};
        excludedCtrls = {'saturate', 'inheritproperties'};
        switch pageName
            case 'General'
                [sheetDims, ctrlPos] = FcnCalcGeneralControlPositions(commonGeom);
                
            case 'Output'
                [sheetDims, ctrlPos] = tl_calc_ctrls_positions(commonGeom, excludedCtrls);
                
            case 'Table'
                [sheetDims, ctrlPos] = FcnCalcTableControlPositions(commonGeom);
                
            case 'Axis#1'
                [sheetDims, ctrlPos] = FcnCalcRowControlPositions(commonGeom);
                
            case 'Axis#2'
                [sheetDims, ctrlPos] = FcnCalcColumnControlPositions(commonGeom);
                
            case 'Map'
                excludedCtrls = [excludedCtrls, {'allscaling', 'scaling', 'type', ...
                    'width', 'element', 'scalarExp', 'unit', 'var'}];
                [sheetDims, ctrlPos] = tl_calc_ctrls_positions(commonGeom, excludedCtrls);
                
            case 'Logging & Autoscaling'
                excludedCtrls = {};
                [sheetDims, ctrlPos] = ...
                    TLManageLoggingCtrls('calcCtrls', commonGeom, sheetDims, excludedCtrls);
                
            case 'Documentation'
                % activate extra controls for table blocks
                bTblBlock = 1;
                bCodeComment = 1;
                [sheetDims, ctrlPos] = ...
                    TLManageDocCtrls('ctrlpos', commonGeom, sheetDims, ...
                    bCodeComment, bTblBlock);
        end
        varargout{1} = sheetDims;
        varargout{2} = ctrlPos;
        
    case 'Create'
        pageName = varargin{1};
        dlgfig   = varargin{2};
        dlgdata  = varargin{3};
        pageNum  = strmatch(pageName, dlgdata.pageNames, 'exact');
        switch pageName
            case 'General'
                dlgdata = FcnCreateGeneralControls(pageNum, dlgfig, dlgdata);
                
            case 'Output'
                dlgdata = TLManageVariableCtrls('create', pageNum, dlgfig, dlgdata);
                dlgdata = TLManageScalingCtrls('create', pageNum, dlgfig, dlgdata);
                
            case 'Table'
                dlgdata = FcnCreateTableControls(pageNum, dlgfig, dlgdata);
                
            case 'Axis#1'
                dlgdata = FcnCreateRowControls(pageNum, dlgfig, dlgdata);
                
            case 'Axis#2'
                dlgdata = FcnCreateColumnControls(pageNum, dlgfig, dlgdata);
                
            case 'Map'
                dlgdata = TLManageVariableCtrls('create', pageNum, dlgfig, dlgdata);
                
            case 'Logging & Autoscaling'
                dlgdata = TLManageLoggingCtrls('create', pageNum, dlgfig, dlgdata);
                
            case 'Documentation'
                dlgdata = FcnCreateDocumentationControls(pageNum, dlgfig, dlgdata);
        end
        dlgdata.pageData{pageNum}.ctrlPos = [];
        varargout{1} = dlgdata;
        
    case 'Manage',
        pageName   = varargin{1};
        dlgfig     = varargin{2};
        dlgdata    = varargin{3};
        pageAction = varargin{4};
        pageNum    = strmatch(pageName, dlgdata.pageNames, 'exact');
        switch pageName
            case 'General'
                [dlgdata, bModified] = FcnManageGeneralControls(pageNum, dlgfig, dlgdata, pageAction);
                
            case 'Output'
                [dlgdata, bModified1] = ...
                    TLManageVariableCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'output');
                % output variable can be vectorized
                currentElement = dlgdata.extdata.output.currentElement;
                [dlgdata, bModified2] = ...
                    TLManageScalingCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'output', currentElement);
                
                bModified = bModified1 || bModified2;
                
            case 'Table'
                [dlgdata, bModified] = FcnManageTableControls(pageNum, dlgfig, dlgdata, pageAction);
                
            case 'Axis#1'
                [dlgdata, bModified] = FcnManageRowControls(pageNum, dlgfig, dlgdata, pageAction);
                
            case 'Axis#2'
                [dlgdata, bModified] = FcnManageColumnControls(pageNum, dlgfig, dlgdata, pageAction);
                
            case 'Map'
                [dlgdata, bModified] = ...
                    TLManageVariableCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'map');
                
            case 'Logging & Autoscaling'
                [dlgdata, bModified] = ...
                    TLManageLoggingCtrls('manage', pageNum, dlgdata, pageAction, 'logdata');
                
            case 'Documentation'
                [dlgdata, bModified] = FcnManageDocumentationControls(pageNum, ...
                    dlgfig, dlgdata, pageAction);
        end
        varargout{1} = dlgdata;
        varargout{2} = bModified ;
        
    case 'ManageSystemIcons',
        dlgfig     = varargin{1};
        dlgdata    = varargin{2};
        pageAction = varargin{3};
        [dlgdata, bModified] = FcnManageSystemIcons(dlgfig,dlgdata,pageAction);
        varargout{1} = dlgdata;
        varargout{2} = bModified;
        
    case 'Update'
        dlgfig    = varargin{1};
        dlgdata   = varargin{2};
        pageNum   = varargin{3};
        
        if dlgdata.bRefreshTool
            FcnRefreshTableTool(dlgfig, dlgdata);
            dlgdata.bRefreshTool = false;
        end
        
        pageName  = dlgdata.pageNames{pageNum};
        switch pageName
            case 'General'
                dlgdata = FcnUpdateGeneralControls(pageNum, dlgfig, dlgdata);
                
            case 'Output'
                dlgdata = TLManageVariableCtrls('update', pageNum, dlgdata, 'output');
                dlgdata = TLManageScalingCtrls('update', pageNum, dlgdata, 'output', []);
                
                TLManageVariableCtrls('setCtrls', pageNum, dlgfig, dlgdata);
                TLManageScalingCtrls('setCtrls', pageNum, dlgfig, dlgdata);
                
            case 'Table'
                dlgdata = FcnUpdateTableControls(pageNum, dlgfig, dlgdata);
                
            case 'Axis#1'
                dlgdata = FcnUpdateRowControls(pageNum, dlgfig, dlgdata);
                
            case 'Axis#2'
                dlgdata = FcnUpdateColumnControls(pageNum, dlgfig, dlgdata);
                
            case 'Map'
                dlgdata = TLManageVariableCtrls('update', pageNum, dlgdata, 'map');
                TLManageVariableCtrls('setCtrls', pageNum, dlgfig, dlgdata);
                
            case 'Logging & Autoscaling'
                dlgdata =  TLManageLoggingCtrls('update',pageNum,dlgdata,'logdata','output');
                TLManageLoggingCtrls('setCtrls',pageNum, dlgfig, dlgdata);
                
            case 'Documentation'
                dlgdata = FcnUpdateDocumentationControls(pageNum, dlgfig, dlgdata);
        end
        varargout{1} = dlgdata;
        
    case 'Apply'
        dlgdata  = varargin{2};
        bClose   = varargin{3};
        [dlgdata, bClose] = tl_apply_blockdata(dlgdata, bClose);
        varargout{1} = dlgdata;
        varargout{2} = bClose;
        
    otherwise
        error(['Invalid action "' action '"']);
        
end


%-----------------------------------------------------------------------------------------
% FcnManageSystemIcons manage actions of toolbar icons
%
% INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   action      action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageSystemIcons(dlgfig, dlgdata, action) %#ok

bModified = false;
switch action
    case 'EditCode'
        % look for associated production code file
        [codefile,blockstr] = get_codefile(dlgdata.model);
        if ~isempty(codefile)
            codeedit(codefile,blockstr);
        end
        
    case 'ViewCode'
        switch dlgdata.pageNames{dlgdata.CurrentPageNum}
            case 'Table'
                blockVar = 'table';
                tl_create_links_to_model('ShowDeclaration',dlgdata.model, blockVar);
            case 'Axis#1'
                blockVar = 'row';
                tl_create_links_to_model('ShowDeclaration',dlgdata.model, blockVar);
            case 'Axis#2'
                blockVar = 'col';
                tl_create_links_to_model('ShowDeclaration',dlgdata.model, blockVar);
            case 'Map'
                blockVar = 'map';
                tl_create_links_to_model('ShowDeclaration',dlgdata.model, blockVar);
            otherwise
                blockVar = 'output';
                tl_create_links_to_model('ShowComputation',dlgdata.model, blockVar);
        end
        
    otherwise
        error('Invalid callback');
        
end % switch(action)


%-----------------------------------------------------------------------------------------
% FcnCalcGeneralControlPositions calculates positions for all controls on general page
%
% INPUT ARGUMENTS
%   commonGeom      common geometry information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims, ctrlPos] = FcnCalcGeneralControlPositions(commonGeom)

% get sheet dimension of output tab
[sheetDims, outputCtrlPos, col, colDelta] = tl_calc_ctrls_positions(commonGeom, ...
    {'allscaling', 'scaling', 'type', 'class', 'var', 'element', 'width', 'address' 'name', 'unit', 'scalarExp', 'inheritproperties'});

strings_and_styles = {...
    'Data Dictionary look-up table object:', 'text';...
    '',                                     'edit';...
    'n',                                    'pushbutton';...
    'Axis#2',                               'text';...
    'Look-up method:',                      'text';...
    'Adapt table values',                   'checkbox';...
    '',                                     'checkbox';...
    'Generate map struct',                  'checkbox';...
    'Use boundary points',                  'checkbox';...
    repmat('x',23),                         'edit';...
    'Launch Table Tool',                    'pushbutton';...
    'Axis_2 (Column)',                      'text';...
    '= 99999 x LSB',                        'text';...
    'Distances:',                           'text';...
    'From:',                                'text';...
    'To:',                                  'text';...
    'Arbitrary factor',                     'checkbox';...
    'less than half of implemented range',  'text'};

[ddLabelSize, ...
    ddEditSize, ...
    ddMenuButtonSize, ...
    editLabelSize, ...
    methodLabelSize, ...
    adaptTableValuesCheckboxSize, ...
    boundCheckboxSize, ...
    generateMapStructCheckboxSize, ...
    addpointsCheckboxSize, ...
    selectEditSize, ...
    tabletoolButtonSize, ...
    selectLabelSize, ...
    distLSBLabelSize, ...
    distLabelSize, ...
    x0LabelSize, ...
    xnLabelSize, ...
    arbdistCheckboxSize, ...
    boundLabelSize] = ...
    ds_get_uicontrol_sizes(commonGeom, strings_and_styles);

% correct height, because on some platforms icon overlapped button boundary; icon height is 18 pixel.
ddMenuButtonSize(2) = max(22, ddMenuButtonSize(2));

% get length of complete line
wholeLength = outputCtrlPos.tlcgoptGroupbox(3) - 2*commonGeom.frameSideEdgeBuffer;
methodPopupSize = [(wholeLength - 2*colDelta/3) / 3, commonGeom.editHeight];
tabletoolButtonSize(1) = (methodPopupSize(1) - colDelta/5) / 2;
% get new columns
widths = repmat(methodPopupSize(1), 1, 3);
[col, colWidth, colDelta, rowDelta] = ds_get_gui_columns(widths, commonGeom);
fromToEditSize = selectEditSize;
fromToEditSize(1) = (methodPopupSize(1) - distLabelSize(1) - xnLabelSize(1) - colDelta/3)/2;
%--------------------------------------------------------------------------
% table options groupbox
cx = commonGeom.figSideEdgeBuffer + commonGeom.sheetSideEdgeBuffer;
cy = commonGeom.bottomSheetOffset + ...
    commonGeom.sheetBottomEdgeBuffer;
tableGroupboxWidth = outputCtrlPos.addoptGroupbox(3);
tableGroupboxHeight = 8 * commonGeom.editHeight ...
    + 2 * commonGeom.checkboxHeight ...
    + 8 * rowDelta ...
    + commonGeom.frameBottomEdgeBuffer ...
    + commonGeom.frameTopEdgeBuffer;
ctrlPos.tableGroupbox = [cx,cy,tableGroupboxWidth,tableGroupboxHeight];

% positions for table controls
% 9th row
cy = commonGeom.frameBottomEdgeBuffer;
cx = col(1);
% autoscale and table tool button
ctrlPos.autoscaleButton = [cx cy tabletoolButtonSize];
ctrlPos.tabletoolButton = [(cx + tabletoolButtonSize(1) + colDelta/3) cy tabletoolButtonSize];

% 8th row
cy = ctrlPos.tabletoolButton(2) + commonGeom.editHeight + rowDelta;

% generate map struct checkbox
cx = col(1);
ctrlPos.generateMapStructCheckbox = [cx cy generateMapStructCheckboxSize];

% row: from label
cx = col(2);
ctrlPos.r0Label = [cx cy x0LabelSize];

% row: from edit field
cx = col(2) + distLabelSize(1);
ctrlPos.r0Edit = [cx cy fromToEditSize];

% row: to label
cx = cx + ctrlPos.r0Edit(3)+ colDelta/3;
ctrlPos.rnLabel = [cx cy xnLabelSize];

% row: to edit field
cx = cx + xnLabelSize(1);
ctrlPos.rnEdit = [cx cy fromToEditSize];

% Column: from label
cx = col(3);
ctrlPos.c0Label = [cx cy x0LabelSize];

% Column: from edit field
cx = cx + distLabelSize(1);
ctrlPos.c0Edit = [cx cy fromToEditSize];

% Column: to label
cx = cx + ctrlPos.c0Edit(3) + colDelta/3;
ctrlPos.cnLabel = [cx cy xnLabelSize];

% Column: to edit field
cx = cx + xnLabelSize(1);
ctrlPos.cnEdit = [cx cy fromToEditSize];

% 7th row
cy = cy + commonGeom.editHeight + rowDelta;

% bounding points checkbox
cx = col(1);
ctrlPos.boundCheckbox = [cx cy boundCheckboxSize];

% bounding label (two lines)
cx = cx + boundCheckboxSize(1) - 5;
ctrlPos.boundLabel = ...
    [cx (cy - boundLabelSize(2) * .67) (boundLabelSize .* [1 2])];

% row: distance label
cx = col(2);
ctrlPos.rDistLabel = [cx cy distLabelSize];

% row: distance edit
cx = cx + distLabelSize(1);
ctrlPos.rDistEdit = [cx cy fromToEditSize];

% row: distance LSB label
cx = ctrlPos.rDistEdit(1) + ctrlPos.rDistEdit(3) + colDelta/3;
ctrlPos.rDistLSBLabel = [cx cy distLSBLabelSize];

% Column: distance label
cx = col(3);
ctrlPos.cDistLabel = [cx cy distLabelSize];

% Column: distance edit
cx = col(3) + distLabelSize(1);
ctrlPos.cDistEdit = [cx cy fromToEditSize];

% Column: distance LSB label
cx = ctrlPos.cDistEdit(1) + ctrlPos.cDistEdit(3) + colDelta/3;
ctrlPos.cDistLSBLabel = [cx cy distLSBLabelSize];

% 6th row
cy = cy + commonGeom.editHeight + rowDelta;

% adapt table values checkbox
cx = col(1);
ctrlPos.adaptTableValuesCheckbox = [cx cy adaptTableValuesCheckboxSize];

% arbitrary factor checkbox
cx = col(2);
ctrlPos.rarbdistCheckbox = [cx cy arbdistCheckboxSize];
cx = col(3);
ctrlPos.carbdistCheckbox = [cx cy arbdistCheckboxSize];

% 5th row
cy = cy + commonGeom.checkboxHeight + rowDelta;

% lookup method popup
cx = col(1);
ctrlPos.methodPopup = [cx cy methodPopupSize];

% lookup search algorithm popup
cx = col(2);
ctrlPos.rsearchPopup = [cx cy methodPopupSize];
cx = col(3);
ctrlPos.csearchPopup = [cx cy methodPopupSize];

% 4th row
cy = cy + commonGeom.editHeight + rowDelta;

% lookup method label
cx = col(1);
ctrlPos.methodLabel = [cx cy methodLabelSize];

% add boundary points checkboxes
cx = col(2);
ctrlPos.raddpointsCheckbox = [cx cy addpointsCheckboxSize];
cx = col(3);
ctrlPos.caddpointsCheckbox = [cx cy addpointsCheckboxSize];

% 3rd row
% table edit field
cx = col(1);
cy = cy + commonGeom.editHeight + rowDelta;
ctrlPos.tEdit = [cx cy methodPopupSize];

% axis edit field
cx = col(2);
ctrlPos.rEdit = [cx cy methodPopupSize];

% Column edit field
cx = col(3);
ctrlPos.cEdit = [cx cy methodPopupSize];

% table lable
cx = col(1);
cy = cy + commonGeom.textHeight + rowDelta;
ctrlPos.tLabel = [cx cy selectLabelSize];

% axis label
cx = col(2);
ctrlPos.rLabel = [cx cy selectLabelSize];

% Column label
cx = col(3);
ctrlPos.cLabel = [cx cy selectLabelSize];

% 2nd row
cy = cy + commonGeom.editHeight + rowDelta;

% DD field
cx = col(1);
dotButtonSize = [2*ddMenuButtonSize(1) ddMenuButtonSize(2)];
ddEditSize(1) = wholeLength - dotButtonSize(1);
ctrlPos.ddEdit = [cx cy ddEditSize];

% select button
cx = cx + ddEditSize(1);
ctrlPos.ddSelectButton = [cx,cy, dotButtonSize];
% DD menu button
cx = cx + ddMenuButtonSize(1);
ctrlPos.ddMenuButton = [cx+2,cy+2,ddMenuButtonSize(1)-4 ddMenuButtonSize(2)-4];


% 1st row
cy = cy + commonGeom.textHeight + rowDelta;

% DD label
cx = col(1);
ctrlPos.ddLabel = [cx cy ddLabelSize];

sheetDims(2) = ...
    commonGeom.sheetTopEdgeBuffer ...
    + ctrlPos.tableGroupbox(4) ...
    + commonGeom.sheetBottomEdgeBuffer;


%-----------------------------------------------------------------------------------------
% FcnCreateGeneralControls creates general controls page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateGeneralControls(pageNum, dlgfig, dlgdata)

Children = dlgdata.pageData{pageNum}.children;
ctrlPos  = dlgdata.pageData{pageNum}.ctrlPos;
pageName = dlgdata.pageNames{pageNum};

defColor = get(0, 'DefaultUIControlBackgroundColor');
userDataMenuButton.cDataEnabled  = tl_get_icon('ArrowHeadDown_10x18', 'BackgroundColor', defColor);
userDataMenuButton.cDataDisabled = tl_get_icon('ArrowHeadDown_10x18_disabled');
userDataSelectButton.cDataEnabled  = tl_get_icon('Browse_Seperator_24x18', 'BackgroundColor', defColor);
userDataSelectButton.cDataDisabled = tl_get_icon('Browse_Seperator_24x18');

% create the tableGroupbox which will contain table options
Children.tableGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Look-up options'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.tableGroupbox);

% dd controls
Children.ddLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             'Data Dictionary look-up table object:', ...
    'Position',           ctrlPos.ddLabel);

Children.ddEdit = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.ddEdit, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''ddEdit'')',pageName));

Children.ddSelectButton = uicontrol( ...
    'Parent',            Children.tableGroupbox, ...
    'Style',             'pushbutton', ...
    'UserData',          userDataSelectButton, ...
    'CData',             userDataSelectButton.cDataEnabled, ...
    'Position',          ctrlPos.ddSelectButton, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''ddSelectButton'')',pageName));

Children.ddMenuButton = uicontrol( ...
    'Parent',            Children.tableGroupbox, ...
    'Style',             'pushbutton', ...
    'UserData',          userDataMenuButton, ...
    'CData',             userDataMenuButton.cDataEnabled, ...
    'Position',          ctrlPos.ddMenuButton, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''ddMenuButton'')',pageName));

% define context menu for DataDictionary browse button
pdlgfig = get(dlgfig,'Parent');
ddCMenu = uicontextmenu('Parent', pdlgfig);
set(Children.ddEdit, 'UIContextMenu', ddCMenu);
set(Children.ddMenuButton, 'UIContextMenu', ddCMenu);
menu.select = uimenu(ddCMenu, ...
    'Label', 'Select', ...
    'Callback', sprintf('tldlg(''%s'',gcbf,''ddSelectButton'')', dlgdata.pageNames{pageNum}));
menu.show = uimenu(ddCMenu, ...
    'Label', 'Show in DD Manager', ...
    'Callback', sprintf('tldlg(''%s'',gcbf,''ddShowDDObject'')', dlgdata.pageNames{pageNum}), ...
    'Separator', 'on');
set(ddCMenu, 'UserData', menu);

% table  controls
Children.rLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             'Axis#1 (row):', ...
    'Position',           ctrlPos.rLabel);

Children.rEdit = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.rEdit, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''rEdit'')',pageName));

Children.cLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             'Axis#2 (column):', ...
    'Position',           ctrlPos.cLabel);

Children.cEdit = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.cEdit, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''cEdit'')',pageName));

Children.tLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             'Table:', ...
    'Position',           ctrlPos.tLabel);

Children.tEdit = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.tEdit, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''tEdit'')',pageName));

Children.adaptTableValuesCheckbox = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Adapt table values', ...
    'Position',           ctrlPos.adaptTableValuesCheckbox, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''adaptTableValuesCheckbox'')',pageName));

Children.boundCheckbox = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'checkbox', ...
    'Position',           ctrlPos.boundCheckbox, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''boundCheckbox'')',pageName));

Children.boundLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'Min',                1, ...
    'Max',                2, ...
    'String',             sprintf('Distances between table entries\nless than half of implemented range'), ...
    'Position',           ctrlPos.boundLabel);

Children.generateMapStructCheckbox = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Generate map struct', ...
    'Value',              dlgdata.data.generatemapstruct, ...
    'Position',           ctrlPos.generateMapStructCheckbox, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''generateMapStructCheckbox'')',pageName));

% search algorithm

Children.rsearchPopup = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'popupmenu', ...
    'BackgroundColor',    'w', ...
    'String',             {'Linear search, start low', ...
    'Linear search, start high', ...
    'Local search', ...
    'Binary search', ...
    'Equidistant with'}, ...
    'Position',           ctrlPos.rsearchPopup, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''rsearchPopup'')',pageName));

Children.csearchPopup = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'popupmenu', ...
    'BackgroundColor',    'w', ...
    'String',             {'Linear search, start low', ...
    'Linear search, start high', ...
    'Local search', ...
    'Binary search', ...
    'Equidistant with'}, ...
    'Position',           ctrlPos.csearchPopup, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''csearchPopup'')',pageName));

% loook-up method popup menu

Children.methodLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             {'Look-up method:'}, ...
    'Position',           ctrlPos.methodLabel);

Children.methodPopup = uicontrol( ...
    'Parent',            Children.tableGroupbox, ...
    'Style',             'popupmenu', ...
    'BackgroundColor',   'w', ...
    'String',            { ...
    'Interpolation - Extrapolation', ...
    'Interpolation - Use End Values', ...
    'Use Input Nearest', ...
    'Use Input Below', ...
    'Use Input Above' ...
    }, ...
    'Position',          ctrlPos.methodPopup, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''methodPopup'')',pageName));

% add boundary points checkboxes

Children.raddpointsCheckbox = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Use boundary points', ...
    'Position',           ctrlPos.raddpointsCheckbox, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''raddpointsCheckbox'')',pageName));

Children.caddpointsCheckbox = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Use boundary points', ...
    'Position',           ctrlPos.caddpointsCheckbox, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''caddpointsCheckbox'')',pageName));

% implementation distance controls

Children.rdistEdit = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.rDistEdit, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''rdistEdit'')',pageName));

Children.rdistLSBLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'Position',           ctrlPos.rDistLSBLabel);

Children.rarbdistCheckbox = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Arbitrary factor', ...
    'Position',           ctrlPos.rarbdistCheckbox , ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''rarbdistCheckbox'')',pageName));

Children.r0Label = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             'From:', ...
    'Position',           ctrlPos.r0Label);

Children.r0Edit = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.r0Edit, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''r0Edit'')',pageName));

Children.rnLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             'To:', ...
    'Position',           ctrlPos.rnLabel);

Children.rnEdit = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.rnEdit, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''rnEdit'')',pageName));

Children.cdistEdit = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.cDistEdit, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''cdistEdit'')',pageName));

Children.cdistLSBLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'Position',           ctrlPos.cDistLSBLabel);

Children.carbdistCheckbox = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Arbitrary factor', ...
    'Position',           ctrlPos.carbdistCheckbox, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''carbdistCheckbox'')',pageName));

Children.c0Label = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             'From:', ...
    'Position',           ctrlPos.c0Label);

Children.c0Edit = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.c0Edit, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''c0Edit'')',pageName));

Children.cnLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             'To:', ...
    'Position',           ctrlPos.cnLabel);

Children.cnEdit = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.cnEdit, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''cnEdit'')',pageName));

Children.cdistLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             'Distances:', ...
    'Position',           ctrlPos.cDistLabel);

Children.rdistLabel = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'text', ...
    'String',             'Distances:', ...
    'Position',           ctrlPos.rDistLabel);

% scale table and table tool button
Children.autoscaleButton = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'pushbutton', ...
    'String',             'Scale Table', ...
    'Position',           ctrlPos.autoscaleButton, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''autoscaleButton'')',pageName));

Children.tabletoolButton = uicontrol( ...
    'Parent',             Children.tableGroupbox, ...
    'Style',              'pushbutton', ...
    'String',             'Launch Table Tool', ...
    'Position',           ctrlPos.tabletoolButton, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''tabletoolButton'')',pageName));

dlgdata.pageData{pageNum}.children = Children;


%-----------------------------------------------------------------------------------------
% FcnManageGeneralControls manages control actions of general page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageGeneralControls(pageNum, dlgfig, dlgdata, pageAction)

bModified = false;
bRefreshTool = false;
Children = dlgdata.pageData{pageNum}.children;
data = dlgdata.data;
panelPos = get(Children.tableGroupbox, 'Position');

switch pageAction
    
    case 'ddEdit'
        % Edit field: Get new module from edit field
        data.blockobject = tl_deblank(get(Children.ddEdit,'String'),2);
        bModified = true;
        
    case 'ddMenuButton',
        FcnSetMenuPosition(Children.ddMenuButton, panelPos(1:2));
        bModified = true;
        
    case 'ddSelectButton'
        data.blockobject = dsdd( 'SelectObject', ...
            'entryPath',       '/Pool/BlockSpecifications', ...
            'CurrentPath',     data.blockobject, ...
            'ObjectKind',      'Block');
        bModified = true;
        
    case 'ddShowDDObject'
        if dsdd('exist', ['/Pool/BlockSpecifications/' data.blockobject]);
            % jump to function object in DD Manager
            ddPath = ['/Pool/BlockSpecifications/' data.blockobject];
            dsddman('Select', ddPath);
        else
            % jump to node in DD Manager
            dsddman('Select', '/Pool');
        end
        
    case 'rEdit'
        rStr = deblank(get(Children.rEdit, 'String'));
        if ~isempty(rStr)
            if strcmp(rStr, 'ddv')
                if isempty(dlgdata.data.row.variable)
                    beep;
                else
                    data.row.value = ['ddv(''', data.row.variable, ''')'];
                    data.row.useddvariablevalue = true;
                end
            else
                data.row.value = rStr;
                % since value was changed without respect to a DD variable,
                % useddvariablevalue is assumed as 'off'
                data.row.useddvariablevalue = false;
            end
            bRefreshTool = true;
        else
            beep;
        end
        bModified = true;
        
    case 'cEdit'
        cStr = deblank(get(Children.cEdit, 'String'));
        if ~isempty(cStr)
            if strcmp(cStr, 'ddv')
                if isempty(dlgdata.data.col.variable)
                    beep;
                else
                    data.col.value = ['ddv(''', data.col.variable, ''')'];
                    data.col.useddvariablevalue = true;
                end
            else
                data.col.value = cStr;
                % since value was changed without respect to a DD variable,
                % useddvariablevalue is assumed as 'off'
                data.col.useddvariablevalue = false;
            end
            bRefreshTool = true;
        else
            beep;
        end
        bModified = true;
        
    case 'tEdit'
        tStr = deblank(get(Children.tEdit, 'String'));
        if ~isempty(tStr)
            if strcmp(tStr, 'ddv')
                if isempty(dlgdata.data.table.variable)
                    beep;
                else
                    data.table.value = ['ddv(''', data.table.variable, ''')'];
                    data.table.useddvariablevalue = true;
                end
            else
                data.table.value = tStr;
                % since value was changed without respect to a DD variable,
                % useddvariablevalue is assumed as 'off'
                data.table.useddvariablevalue = false;
            end
            bRefreshTool = true;
        else
            beep;
        end
        bModified = true;
        
    case 'adaptTableValuesCheckbox'
        data.adapttablevalues = get(Children.adaptTableValuesCheckbox, 'Value');
        bModified = true;
        
    case 'boundCheckbox'
        data.bounded = get(Children.boundCheckbox, 'Value');
        bModified = true;
        
    case 'generateMapStructCheckbox'
        data.generatemapstruct = get(Children.generateMapStructCheckbox, 'Value');
        bModified = true;
        
    case 'methodPopup'
        data.lookupmeth = get(Children.methodPopup, 'Value');
        if ~strcmp(get_param(dlgdata.model,'BlockType'), 'Lookup2D') && data.lookupmeth == 3
            data.lookupmeth = 4;    % use input below            
        end

        % addpoints property is only valid for Interpolation methods
        data.row.addpoints = data.row.addpoints && data.lookupmeth <= 2;
        data.col.addpoints = data.col.addpoints && data.lookupmeth <= 2;
        bModified = true;
        bRefreshTool = true;
        
    case 'rsearchPopup'
        search = get(Children.rsearchPopup, 'Value');
        bModified = true;
        
        % refresh tool if searchPopup changed from or to equidistant spacing
        bRefreshTool = (data.row.search ~= 5 && search == 5) ...
            || (data.row.search == 5 && search ~= 5);
        data.row.search = search;
        
    case 'csearchPopup'
        search = get(Children.csearchPopup, 'Value');
        bModified = true;
        
        % refresh tool if searchPopup changed from or to equidistant spacing
        bRefreshTool = (data.col.search ~= 5 && search == 5) ...
            || (data.col.search == 5 && search ~= 5);
        data.col.search = search;
        
    case 'raddpointsCheckbox'
        data.row.addpoints = get(Children.raddpointsCheckbox, 'Value');
        bRefreshTool = true;
        bModified = true;
        
    case 'caddpointsCheckbox'
        data.col.addpoints = get(Children.caddpointsCheckbox, 'Value');
        bRefreshTool = true;
        bModified = true;
        
    case 'tabletoolButton'
        % put tool dialog into the foreground if it exists, create a new one
        % otherwise
        if ishandle(dlgdata.toolfig)
            figure(dlgdata.toolfig);
        else
            bModified = true;
            hdlgfig = get(dlgfig,'Parent');
            set(hdlgfig, 'Pointer', 'watch');
            dlgdata.toolfig = tl_open_toolfig( ...
                dlgdata.model, dlgdata.maskType, data);
            set(hdlgfig,'Pointer', 'arrow');
        end
        
    case 'autoscaleButton'
        ds_error_none;
        [data, bModified, msgstruct] = tl_scale_parameters( ...
            dlgdata.model, data);
        ds_error_register(msgstruct);
        ds_msgdlg('Update', ...
            'Title', ['Scaling of Look-up Table ' ...
            get_tlsubsystempath(dlgdata.model) ], ...
            'ShowErrors', 'yes', ...
            'ShowNotes', 'yes', ...
            'ShowWarnings', 'yes');
        bRefreshTool = bModified;
        
    case {'rdistEdit', 'cdistEdit'}
        if strcmp(pageAction, 'rdistEdit')
            field = 'row';
        else
            field = 'col';
        end
        distance = eval(get(Children.(pageAction), 'String'), '[]');
        if numel(distance) == 1 && ~isnan(distance)
            distance = real(distance);
            if distance > 0
                if ds_isa(['/Pool/Typedefs/', data.(field).type], 'integertype')
                    ndist = round(distance / data.(field).lsb);
                    if ndist == 0
                        ndist = 1;
                    end
                    if data.(field).arbdistance == 0
                        ndist = 2^round(log2(ndist));
                    end
                    [maxint, minint] = tl_int_bounds(data.(field).type);
                    if ndist < (maxint - minint)
                        data.(field).distance = ndist * data.(field).lsb;
                        bModified = true;
                    end
                else
                    data.(field).distance = distance;
                    bModified = true;
                end
            end
        end
        bRefreshTool = bModified;
        
    case {'rarbdistCheckbox', 'carbdistCheckbox'}
        if strcmp(pageAction, 'rarbdistCheckbox')
            field = 'row';
        else
            field = 'col';
        end
        arbdistance = get(Children.(pageAction), 'Value');
        data.(field).arbdistance = arbdistance;
        bModified = true;
        bRefreshTool = true;
        
    case {'r0Edit', 'c0Edit'}
        if strcmp(pageAction, 'r0Edit')
            field = 'row';
        else
            field = 'col';
        end
        x0str = get(Children.(pageAction), 'String');
        if ~isempty(x0str)
            x0 = str2double(x0str);
            if ~isnan(x0) && numel(x0) == 1
                x0 = real(x0);
                if ~isempty(data.(field).xn)
                    if x0 < data.(field).xn
                        data.(field).x0 = x0;
                    else
                        beep;
                    end
                else
                    data.(field).x0 = x0;
                end
            else
                beep;
            end
        else
            data.(field).x0 = [];
        end
        bModified = true;
        bRefreshTool = true;
        
    case {'rnEdit', 'cnEdit'}
        if strcmp(pageAction, 'rnEdit')
            field = 'row';
        else
            field = 'col';
        end
        xnstr = get(Children.(pageAction), 'String');
        if ~isempty(xnstr)
            xn = str2double(xnstr);
            if ~isnan(xn) && numel(xn) == 1
                xn = real(xn);
                if ~isempty(data.(field).x0)
                    if xn > data.(field).x0
                        data.(field).xn = xn;
                    else
                        beep;
                    end
                else
                    data.(field).xn = xn;
                end
            else
                beep;
            end
        else
            data.(field).xn = [];
        end
        bModified = true;
        bRefreshTool = true;
end

if bModified
    dlgdata.data = data;
end

dlgdata.bRefreshTool = bRefreshTool;


%-------------------------------------------------------------------------------
% FcnSetMenuPosition calculates position of contextmenu
%
% INPUT ARGUMENTS
%   ctrlHandle  handle of control
%   panelStart  cx position of panel
%
% OUTPUT ARGUMENTS
%   - / -
%-------------------------------------------------------------------------------
function FcnSetMenuPosition(ctrlHandle, panelStart)

pos = get(ctrlHandle, 'Position') + [panelStart 0 0];
cmenu = get(ctrlHandle, 'UIContextmenu');
commonGeom = ds_get_common_geometry;
textExtent = commonGeom.textExtent;
labelStrings = get(get(cmenu, 'Children'), 'Label');
maxext = 0;
for k = 1 : numel(labelStrings)
    set(textExtent, 'String', labelStrings{k});
    ext = get(textExtent, 'Extent');
    maxext = max(maxext, ext(3));
end
position = [pos(1)-32-maxext, pos(2)];
set(cmenu, 'Position', position, 'Visible', 'on');


%--------------------------------------------------------------------------
% FcnUpdateGeneralControls updates the controls of the general tab
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateGeneralControls(pageNum, dlgfig, dlgdata)

Children = dlgdata.pageData{pageNum}.children;
data = dlgdata.data;
enumStruct = tl_manage_blockset('GetEnums');
idx = strcmp({enumStruct.name},'LookupMethEnum');
lookupMethodEnums = enumStruct(idx).strings; 
if strcmp(get_param(dlgdata.model,'BlockType'),'Lookup2D')
    lookupMethodValues = enumStruct(idx).values;    % 1:5
else % SL n-D LUT block
    lookupMethodValues = [1 2 4];
end

bIsFullVs = dlgdata.bIsFullVs;
if bIsFullVs && dlgdata.bDSDDMan
    defaultStatusDD = 'on';
else
    defaultStatusDD = 'inactive';
end

[data, extdata] = tl_sync_dd_blockdata(data, 'BlockType', dlgdata.maskType);

ddEditCtrlStatus = struct('enable', defaultStatusDD);
ddEditCtrlStatus.string = data.blockobject;
ddEditCtrlStatus.iserror = 0;

ddSelectButtonCtrlStatus = struct('enable', defaultStatusDD); %#ok<NASGU>
ddMenuButtonCtrlStatus = struct('enable', defaultStatusDD); %#ok<NASGU>
% set status of context menu controls:
ddCMenu = get(Children.ddMenuButton, 'UIContextMenu');
ddMenu = get(ddCMenu, 'UserData');

menuSelectStatus = struct('enable', flag2str(bIsFullVs));
UserData = get(ddMenu.select, 'UserData');
UserData.ctrlStatus = menuSelectStatus;
set(ddMenu.select, 'UserData', UserData);

menuShowStatus = struct('enable', flag2str(dlgdata.bDSDDMan));
UserData = get(ddMenu.show, 'UserData');
UserData.ctrlStatus = menuShowStatus;
set(ddMenu.show, 'UserData', UserData);

% Update extra controls
% values and look-up method is independend of blockset mode
tEditCtrlStatus = struct('enable', FcnbEnabled(extdata.table.bWritable.value, 1));
rEditCtrlStatus = struct('enable', FcnbEnabled(extdata.row.bWritable.value, 1));
cEditCtrlStatus = struct('enable', FcnbEnabled(extdata.col.bWritable.value, 1));
methodPopupCtrlStatus = struct('enable', FcnbEnabled(extdata.bWritable.lookupmeth, 1), ...
    'string', {get(Children.methodPopup, 'String')}, ...
    'value', 1);
rsearchPopupCtrlStatus = struct('enable', FcnbEnabled(extdata.row.bWritable.search, bIsFullVs), ...
    'string', {get(Children.rsearchPopup, 'String')}, ...
    'value', 1);
csearchPopupCtrlStatus = struct('enable', FcnbEnabled(extdata.col.bWritable.search, bIsFullVs), ...
    'string', {get(Children.csearchPopup, 'String')}, ...
    'value', 1);

adaptTableValuesCheckboxCtrlStatus = struct('enable', FcnbEnabled(extdata.bWritable.adapttablevalues, bIsFullVs));
carbdistCheckboxCtrlStatus = struct('enable', FcnbEnabled(extdata.col.bWritable.arbdistance, bIsFullVs));
boundStatus = FcnbEnabled(extdata.bWritable.bounded, bIsFullVs);
boundCheckboxCtrlStatus = struct('enable', boundStatus);
if strcmp(boundStatus, 'inactive')
    boundStatus = 'off';
end
boundLabelCtrlStatus = struct('enable', boundStatus); %#ok<NASGU>
generateMapStructCheckboxCtrlStatus = struct('enable', FcnbEnabled(extdata.bWritable.generatemapstruct, bIsFullVs));

tEditCtrlStatus.string = data.table.value;
[tmp, tmp, tmp, bCompliant] = tl_eval_table(data.table, false, true); %#ok<ASGLU>
tEditCtrlStatus.iserror = ~bCompliant;
rEditCtrlStatus.string = data.row.value;
[tmp, tmp, tmp, bCompliant] = tl_eval_table(data.row, true); %#ok<ASGLU>
rEditCtrlStatus.iserror = ~bCompliant;
cEditCtrlStatus.string = data.col.value;
[tmp, tmp, tmp, bCompliant] = tl_eval_table(data.col, true); %#ok<ASGLU>
cEditCtrlStatus.iserror = ~bCompliant;
if any(data.lookupmeth == lookupMethodValues)
    methodPopupCtrlStatus.string = lookupMethodEnums(lookupMethodValues);
    methodPopupCtrlStatus.value = find(strcmp(lookupMethodEnums{data.lookupmeth}, methodPopupCtrlStatus.string));
else
    methodPopupCtrlStatus.iserror = 1;
    methodPopupCtrlStatus.value = numel(lookupMethodValues)+1;
    methodPopupCtrlStatus.string = [lookupMethodEnums(lookupMethodValues); lookupMethodEnums(data.lookupmeth)];
end
rsearchPopupCtrlStatus.value = data.row.search;
csearchPopupCtrlStatus.value = data.col.search;
adaptTableValuesCheckboxCtrlStatus.value = data.adapttablevalues;
carbdistCheckboxCtrlStatus.value = data.col.arbdistance;
boundCheckboxCtrlStatus.value = data.bounded;
generateMapStructCheckboxCtrlStatus.value = data.generatemapstruct;

bRIntegerType = ds_isa(['/Pool/Typedefs/',data.row.type],  'integertype');
[data.row, x0str, xnstr, ndiststr, diststr, bEquidistant] = ...
    FcnManageEquidistantSpacing(data.row, bRIntegerType);

bAddpointsEnable = extdata.row.bWritable.addpoints && ~bEquidistant && bRIntegerType && data.lookupmeth <= 2;
raddpointsCheckboxCtrlStatus = struct('enable', FcnbEnabled(bAddpointsEnable, bIsFullVs));
raddpointsCheckboxCtrlStatus.value = data.row.addpoints && ...
    ~bEquidistant && bRIntegerType && data.lookupmeth <= 2;

bArbdistEnable = extdata.row.bWritable.arbdistance && bEquidistant && bRIntegerType;
rarbdistCheckboxCtrlStatus = struct('enable', FcnbEnabled(bArbdistEnable, bIsFullVs));
rarbdistCheckboxCtrlStatus.value = data.row.arbdistance;

bDistEnable = extdata.row.bWritable.distance && bEquidistant;
rdistLSBLabelCtrlStatus = struct('enable', FcnbEnabled(bDistEnable, bIsFullVs));
rdistEditCtrlStatus = struct('enable', FcnbEnabled(bDistEnable, bIsFullVs));
rdistLSBLabelCtrlStatus.string = diststr;
rdistEditCtrlStatus.string = ndiststr;

bX0Enable = extdata.row.bWritable.x0 && bEquidistant;
r0EditCtrlStatus = struct('enable', FcnbEnabled(bX0Enable, bIsFullVs));
r0EditCtrlStatus.string = x0str;
bXnEnable = extdata.row.bWritable.xn && bEquidistant;
rnEditCtrlStatus = struct('enable', FcnbEnabled(bXnEnable, bIsFullVs));
rnEditCtrlStatus.string = xnstr;

bCIntegerType = ds_isa(['/Pool/Typedefs/',data.col.type],  'integertype');
[data.col, x0str, xnstr, ndiststr, diststr, bEquidistant] = ...
    FcnManageEquidistantSpacing(data.col, bCIntegerType);

bAddpointsEnable = extdata.col.bWritable.addpoints && ~bEquidistant && bCIntegerType && data.lookupmeth <= 2;
caddpointsCheckboxCtrlStatus = struct('enable', FcnbEnabled(bAddpointsEnable, bIsFullVs));
caddpointsCheckboxCtrlStatus.value = data.col.addpoints && ...
    ~bEquidistant && bRIntegerType && data.lookupmeth <= 2;

bArbdistEnable = extdata.col.bWritable.arbdistance && bEquidistant && bCIntegerType;
carbdistCheckboxCtrlStatus = struct('enable', FcnbEnabled(bArbdistEnable, bIsFullVs));
carbdistCheckboxCtrlStatus.value = data.col.arbdistance;

bDistEnable = extdata.col.bWritable.distance && bEquidistant;
cdistLSBLabelCtrlStatus = struct('enable', FcnbEnabled(bDistEnable, bIsFullVs));
cdistEditCtrlStatus = struct('enable', FcnbEnabled(bDistEnable, bIsFullVs));
cdistLSBLabelCtrlStatus.string = diststr;
cdistEditCtrlStatus.string = ndiststr;

bX0Enable = extdata.col.bWritable.x0 && bEquidistant;
c0EditCtrlStatus = struct('enable', FcnbEnabled(bX0Enable, bIsFullVs));
c0EditCtrlStatus.string = x0str;
bXnEnable = extdata.col.bWritable.xn && bEquidistant;
cnEditCtrlStatus = struct('enable', FcnbEnabled(bXnEnable, bIsFullVs));
cnEditCtrlStatus.string = xnstr;

% initialize scale button status
autoscaleButtonCtrlStatus = struct('enable', 'on');
tabletoolButtonCtrlStatus = struct('enable', 'on');
% activation of 'Scale Table' button
% special behaviour of table blocks: Scale button must be disabled if 'no
% autoscaling' is selected and inactive bei output-typ=bool oder float
bOutputInteger = ds_isa(['/Pool/Typedefs/', data.output.type], ...
    'integertype');
bAutoscEnable = bOutputInteger ...
    && isempty(dsdd('GetConstraintsScalingRef', ...
    ['/Pool/Typedefs/', data.output.type])) ...
    && isempty(data.output.scaling);
bScaleButtonEnable  = bIsFullVs && bAutoscEnable && data.autoscaling.mode == 1;
bIsGenericTable = isempty(data.blockobject);
autoscaleButtonCtrlStatus.enable = flag2str(bScaleButtonEnable && bIsGenericTable);
tabletoolButtonCtrlStatus.enable = flag2str(bIsFullVs);

% set control status
ctrlsList = { ...
    'ddEdit' ...
    'ddSelectButton' ...
    'ddMenuButton' ...
    'autoscaleButton' ...
    'tabletoolButton' ...
    'rdistEdit' ...
    'cdistEdit' ...
    'tEdit' ...
    'rEdit' ...
    'cEdit' ...
    'r0Edit' ...
    'c0Edit' ...
    'rnEdit' ...
    'cnEdit' ...
    'raddpointsCheckbox' ...
    'rarbdistCheckbox' ...
    'caddpointsCheckbox' ...
    'carbdistCheckbox' ...
    'methodPopup' ...
    'adaptTableValuesCheckbox' ...
    'boundCheckbox' ...
    'boundLabel' ...
    'generateMapStructCheckbox' ...
    'rsearchPopup' ...
    'rdistLSBLabel' ...
    'csearchPopup' ...
    'cdistLSBLabel'};
for ctrlsNo = 1:numel(ctrlsList)
    ctrl = Children.(ctrlsList{ctrlsNo});
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end

% set control status of table parameter groupbox controls
TLSetCtrlsStatus(dlgfig, Children, ctrlsList)


%-----------------------------------------------------------------------------------------
% FcnRefreshTableTool refreshes the tool dialog; No action if tool does not exist.
%
% INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   - / -
%-----------------------------------------------------------------------------------------
function FcnRefreshTableTool(dlgfig,dlgdata)

% return if figure window of table tool doesn't exist
if ~ishandle(dlgdata.toolfig)
    return;
end

% change mouse pointer shape
set(dlgfig, 'Pointer', 'watch');

% evaluate row, column and table strings
r = tl_eval_table(dlgdata.data.row, true);
c = tl_eval_table(dlgdata.data.col, true);
t = tl_eval_table(dlgdata.data.table, false, true);

% invoke table tool
name = get_param(dlgdata.model, 'Name');
tl_2dtable_tool('refresh', r, c, t, dlgdata.data, name, dlgdata.toolfig);

% restore mouse pointer shape
set(dlgfig, 'Pointer', 'arrow');

%-----------------------------------------------------------------------------------------
% FcnCalcTableControlPositions calculates positions for all controls on Table page
%
% INPUT ARGUMENTS
%   commonGeom      common geometry information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims, ctrlPos] = FcnCalcTableControlPositions(commonGeom)

excludedCtrls = {'saturate', 'inheritproperties', 'width', 'element', 'scalarExp'};
[sheetDims, ctrlPos, col, colDelta, rowDelta] = ...
    tl_calc_ctrls_positions(commonGeom, excludedCtrls);

strings_and_styles = { ...
    'Table:', 'text'
    'Use value of Data Dictionary variable', 'checkbox'};

[tableLabelSize, useDDValueCheckboxSize] = ds_get_uicontrol_sizes(commonGeom, strings_and_styles);

% control positions of controls of table options group box
% define new height for addoptGroupbox
ctrlPos.addoptGroupbox(4) = commonGeom.editHeight ...
    + commonGeom.checkboxHeight ...
    + rowDelta ...
    + commonGeom.frameBottomEdgeBuffer ...
    + commonGeom.frameTopEdgeBuffer;

%---------------------------------------
% 2nd row
cy = commonGeom.frameBottomEdgeBuffer;

% ddv checkbox
cx = col(2);
ctrlPos.useDDValueCheckbox = [cx, cy, useDDValueCheckboxSize];

%---------------------------------------
% 1st row
cy = cy + commonGeom.checkboxHeight + rowDelta;

% table options label
cx = col(1);
ctrlPos.tableLabel  = [cx cy tableLabelSize];

% table options edit field
cx = ctrlPos.descEdit(1);
ctrlPos.tableEdit  = [cx cy ctrlPos.descEdit(3:4)];

% increase sheet dimensions
sheetDims(2) = sheetDims(2) ...
    + ctrlPos.addoptGroupbox(4) ...
    + commonGeom.textHeight;

%-----------------------------------------------------------------------------------------
% FcnCreateTableControls creates Table controls page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateTableControls(pageNum, dlgfig, dlgdata)

% invoke standard function to create scaling controls
dlgdata = TLManageVariableCtrls('create', pageNum, dlgfig, dlgdata);
dlgdata = TLManageScalingCtrls('create', pageNum, dlgfig, dlgdata);

Children = dlgdata.pageData{pageNum}.children;
ctrlPos = dlgdata.pageData{pageNum}.ctrlPos;
pageName = dlgdata.pageNames{pageNum};

tableEditLabeltext = 'Table:';
tableEditLabelPos  = ctrlPos.tableLabel;
tableEditPos   = ctrlPos.tableEdit;

% create the addoptGroupbox which will contain table values
Children.addoptGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Table values'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.addoptGroupbox);

% inputs controls
Children.tEditLabel = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'Style',              'text', ...
    'String',             tableEditLabeltext, ...
    'Position',           tableEditLabelPos);

Children.tEdit = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           tableEditPos, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''tEdit'')',pageName));

Children.useDDValueCheckbox = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Use value of Data Dictionary variable', ...
    'Position',           ctrlPos.useDDValueCheckbox, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''useDDValueCheckbox'')',pageName));

dlgdata.pageData{pageNum}.children = Children;

%-----------------------------------------------------------------------------------------
% FcnManageTableControls manages Table page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata,bModified] = FcnManageTableControls(pageNum, dlgfig, dlgdata, pageAction)

bRefreshTool = false;
Children = dlgdata.pageData{pageNum}.children;

switch pageAction
    
    case 'tEdit'
        tStr = deblank(get(Children.tEdit, 'String'));
        if ~isempty(tStr)
            if strcmp(tStr, 'ddv')
                if isempty(dlgdata.data.table.variable)
                    beep;
                else
                    dlgdata.data.table.value = ['ddv(''', dlgdata.data.table.variable, ''')'];
                    dlgdata.data.table.useddvariablevalue = true;
                end
            else
                dlgdata.data.table.value = tStr;
            end
            bRefreshTool = true;
        else
            beep;
        end
        bModified = true;
        
    case 'useDDValueCheckbox'
        if get(Children.useDDValueCheckbox, 'Value')
            dlgdata.data.table.value = ['ddv(''', dlgdata.data.table.variable, ''')'];
            dlgdata.data.table.useddvariablevalue = true;
        else
            dlgdata.data.table.useddvariablevalue = false;
        end
        bModified = true;
        bRefreshTool = true;
        
    otherwise
        [dlgdata, bModified1] = ...
            TLManageVariableCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'table');
        [dlgdata, bModified2] = ...
            TLManageScalingCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'table');
        bModified = bModified1 | bModified2;
        bRefreshTool = bModified;
        
end

dlgdata.bRefreshTool = bRefreshTool;


%--------------------------------------------------------------------------
% FcnUpdateTableControls updates the controls of the Table tab
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateTableControls(pageNum, dlgfig, dlgdata)

Children = dlgdata.pageData{pageNum}.children;
dlgdata = TLManageVariableCtrls('update', pageNum, dlgdata, 'table');
data = dlgdata.data;

% get minima and maxima of table data
[t, tmin, tmax, bCompliant] = tl_eval_table(dlgdata.data.table, false, true);

constraint = [];
if ~isempty(t) && bCompliant
    constraint = [tmin tmax];
end
dlgdata = TLManageScalingCtrls('update', pageNum, dlgdata, 'table', constraint);

% table value cannot be edited if a look-up table object specifies all
% block data
bWritable = dlgdata.pageData{pageNum}.bWritable.value && ~dlgdata.data.table.useddvariablevalue;
tEditCtrlStatus = struct('enable', FcnbEnabled(bWritable, 1));
tEditCtrlStatus.string = data.table.value;
tEditCtrlStatus.iserror = ~bCompliant;

% status of ddv checkbox
bWritable = dlgdata.pageData{pageNum}.bWritable.value && ~isempty(dlgdata.data.table.variable);
useDDValueCheckboxCtrlStatus.enable = flag2str(bWritable);
useDDValueCheckboxCtrlStatus.value = dlgdata.data.table.useddvariablevalue;

% read scaling controls' UserData
simulatedLabelCtrlStatus = tl_get_control_userdata(Children.simulatedLabel);
upperSimulatedValueCtrlStatus = tl_get_control_userdata(Children.upperSimulatedValue);
lowerSimulatedValueCtrlStatus = tl_get_control_userdata(Children.lowerSimulatedValue);

if ~isempty(t) && bCompliant
    minstr = sprintf('%0.5g', tmin);
    maxstr = sprintf('%0.5g', tmax);
else
    minstr = 'n.a.';
    maxstr = 'n.a.';
end

simulatedLabelCtrlStatus.string = 'of matrix';
upperSimulatedValueCtrlStatus.string = maxstr;
lowerSimulatedValueCtrlStatus.string = minstr;

ctrlsList = { ...
    'tEdit' ...
    'simulatedLabel' ...
    'upperSimulatedValue' ...
    'lowerSimulatedValue' ...
    'useDDValueCheckbox'};
for ctrlsNo = 1:numel(ctrlsList)
    ctrl = Children.(ctrlsList{ctrlsNo});
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end

% set control status of variable, scaling and table parameter groupbox controls
TLManageVariableCtrls('setCtrls', pageNum, dlgfig, dlgdata);
TLManageScalingCtrls('setCtrls', pageNum, dlgfig, dlgdata);
TLSetCtrlsStatus(dlgfig, Children, {'tEdit', 'useDDValueCheckbox'})


%-----------------------------------------------------------------------------------------
% FcnCalcRowControlPositions calculates positions for all controls on Row page
%
% INPUT ARGUMENTS
%   commonGeom      common geometry information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims, ctrlPos] = FcnCalcRowControlPositions(commonGeom)

excludedCtrls = {'saturate', 'inheritproperties', 'width', 'element', 'scalarExp'};
[sheetDims, ctrlPos, col, colDelta, rowDelta] = ...
    tl_calc_ctrls_positions(commonGeom, excludedCtrls);

strings_and_styles = {'Axis#1 (row):', 'text'
    'Use value of Data Dictionary variable', 'checkbox'};

[tableLabelSize, useDDValueCheckboxSize] = ds_get_uicontrol_sizes(commonGeom, strings_and_styles);

% control positions of controls of table options group box
% define new height for addoptGroupbox
ctrlPos.addoptGroupbox(4) = commonGeom.editHeight ...
    + commonGeom.checkboxHeight ...
    + rowDelta ...
    + commonGeom.frameBottomEdgeBuffer ...
    + commonGeom.frameTopEdgeBuffer;

%---------------------------------------
% 2nd row
cy = commonGeom.frameBottomEdgeBuffer;

% ddv checkbox
cx = col(1) + tableLabelSize(1) + colDelta/3;
ctrlPos.useDDValueCheckbox = [cx, cy, useDDValueCheckboxSize];

%---------------------------------------
% 1st row
cy = cy + commonGeom.checkboxHeight + rowDelta;

% table options label
cx = col(1);
ctrlPos.tableLabel  = [cx cy tableLabelSize];

% table options edit field
cx = cx + tableLabelSize(1) + colDelta/3;
dx = ctrlPos.descEdit(3) - (cx - ctrlPos.descEdit(1));
ctrlPos.tableEdit  = [cx cy dx  ctrlPos.descEdit(4)];

% increase sheet dimensions
sheetDims(2) = sheetDims(2) ...
    + ctrlPos.addoptGroupbox(4) ...
    + commonGeom.textHeight;


%-----------------------------------------------------------------------------------------
% FcnCreateRowControls creates Axis controls page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateRowControls(pageNum, dlgfig, dlgdata)

% invoke standard function to create scaling controls
dlgdata = TLManageVariableCtrls('create', pageNum, dlgfig, dlgdata);
dlgdata = TLManageScalingCtrls('create', pageNum, dlgfig, dlgdata);

Children = dlgdata.pageData{pageNum}.children;
ctrlPos = dlgdata.pageData{pageNum}.ctrlPos;
pageName = dlgdata.pageNames{pageNum};

rEditLabeltext = 'Axis#1 (row):';
rEditLabelPos  = ctrlPos.tableLabel;
rEditPos   = ctrlPos.tableEdit;

% create the addoptGroupbox which will contain table values
Children.addoptGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Axis values'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.addoptGroupbox);

% inputs controls
Children.rEditLabel = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'Style',              'text', ...
    'String',             rEditLabeltext, ...
    'Position',           rEditLabelPos);

Children.rEdit = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           rEditPos, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''rEdit'')',pageName));

Children.useDDValueCheckbox = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Use value of Data Dictionary variable', ...
    'Position',           ctrlPos.useDDValueCheckbox, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''useDDValueCheckbox'')',pageName));

dlgdata.pageData{pageNum}.children = Children;


%-----------------------------------------------------------------------------------------
% FcnManageRowControls manages Axis page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata,bModified] = FcnManageRowControls(pageNum, dlgfig, dlgdata, pageAction)

bRefreshTool = 0;
Children = dlgdata.pageData{pageNum}.children;

switch pageAction
    
    case 'rEdit'
        rStr = deblank(get(Children.rEdit, 'String'));
        if ~isempty(rStr)
            if strcmp(rStr, 'ddv')
                if isempty(dlgdata.data.row.variable)
                    beep;
                else
                    dlgdata.data.row.value = ['ddv(''', dlgdata.data.row.variable, ''')'];
                    dlgdata.data.row.useddvariablevalue = true;
                end
            else
                dlgdata.data.row.value = rStr;
            end
            bRefreshTool = true;
        else
            beep;
        end
        bModified = true;
        
    case 'useDDValueCheckbox'
        if get(Children.useDDValueCheckbox, 'Value')
            dlgdata.data.row.value = ['ddv(''', dlgdata.data.row.variable, ''')'];
            dlgdata.data.row.useddvariablevalue = true;
        else
            dlgdata.data.row.useddvariablevalue = false;
        end
        bModified = true;
        bRefreshTool = true;
        
    otherwise
        [dlgdata, bModified1] = ...
            TLManageVariableCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'row');
        [dlgdata, bModified2] = ...
            TLManageScalingCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'row');
        
        bModified = bModified1 | bModified2;
        bRefreshTool = bModified;
        
end

dlgdata.bRefreshTool = bRefreshTool;


%--------------------------------------------------------------------------
% FcnUpdateRowControls updates the controls of the Axis tab
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateRowControls(pageNum, dlgfig, dlgdata)

Children = dlgdata.pageData{pageNum}.children;
dlgdata = TLManageVariableCtrls('update', pageNum, dlgdata, 'row');
data = dlgdata.data;
% get minima and maxima of axis data
[r, rmin, rmax, bCompliant] = tl_eval_table(dlgdata.data.row, true);

constraint = [];
if bCompliant
    constraint = [rmin rmax];
end
dlgdata = TLManageScalingCtrls('update', pageNum, dlgdata, 'row', constraint);

% table value cannot be edited if a look-up table object specifies all
% block data
bWritable = dlgdata.pageData{pageNum}.bWritable.value && ~dlgdata.data.row.useddvariablevalue;
rEditCtrlStatus = struct('enable', FcnbEnabled(bWritable, 1));
rEditCtrlStatus.string = data.row.value;
rEditCtrlStatus.iserror = ~bCompliant;

% status of ddv checkbox
bWritable = dlgdata.pageData{pageNum}.bWritable.value && ~isempty(dlgdata.data.row.variable);
useDDValueCheckboxCtrlStatus.enable = flag2str(bWritable);
useDDValueCheckboxCtrlStatus.value = dlgdata.data.row.useddvariablevalue;

% read scaling controls' UserData
simulatedLabelCtrlStatus = tl_get_control_userdata(Children.simulatedLabel);
upperSimulatedValueCtrlStatus = tl_get_control_userdata(Children.upperSimulatedValue);
lowerSimulatedValueCtrlStatus = tl_get_control_userdata(Children.lowerSimulatedValue);

if ~isempty(r) && bCompliant
    minstr = sprintf('%0.5g', rmin);
    maxstr = sprintf('%0.5g', rmax);
else
    minstr = 'n.a.';
    maxstr = 'n.a.';
end

simulatedLabelCtrlStatus.string = 'of vector';
upperSimulatedValueCtrlStatus.string = maxstr;
lowerSimulatedValueCtrlStatus.string = minstr;

% set control status
ctrlsList = { ...
    'rEdit' ...
    'simulatedLabel' ...
    'upperSimulatedValue' ...
    'lowerSimulatedValue' ...
    'useDDValueCheckbox'};
for ctrlsNo = 1:numel(ctrlsList)
    ctrl = Children.(ctrlsList{ctrlsNo});
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end

% set control status of variable, scaling and table parameter groupbox controls
TLManageVariableCtrls('setCtrls', pageNum, dlgfig, dlgdata);
TLManageScalingCtrls('setCtrls', pageNum, dlgfig, dlgdata);
TLSetCtrlsStatus(dlgfig, Children, {'rEdit', 'useDDValueCheckbox'})

%-----------------------------------------------------------------------------------------
% FcnCalcColumnControlPositions calculates positions for all controls on Column page
%
% INPUT ARGUMENTS
%   commonGeom      common geometry information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims, ctrlPos] = FcnCalcColumnControlPositions(commonGeom)

excludedCtrls = {'saturate', 'inheritproperties', 'width', 'element', 'scalarExp'};
[sheetDims, ctrlPos, col, colDelta, rowDelta] = ...
    tl_calc_ctrls_positions(commonGeom, excludedCtrls);

strings_and_styles = { ...
    'Axis#2 (column):', 'text'
    'Use value of Data Dictionary variable', 'checkbox'};

[tableLabelSize, useDDValueCheckboxSize] = ds_get_uicontrol_sizes(commonGeom, strings_and_styles);

% control positions of controls of table options group box
% define new height for addoptGroupbox
ctrlPos.addoptGroupbox(4) = commonGeom.editHeight ...
    + commonGeom.checkboxHeight ...
    + rowDelta ...
    + commonGeom.frameBottomEdgeBuffer ...
    + commonGeom.frameTopEdgeBuffer;

%---------------------------------------
% 2nd row
cy = commonGeom.frameBottomEdgeBuffer;

% ddv checkbox
cx = col(1) + tableLabelSize(1) + colDelta/3;
ctrlPos.useDDValueCheckbox = [cx, cy, useDDValueCheckboxSize];

%---------------------------------------
% 1st row
cy = cy + commonGeom.checkboxHeight + rowDelta;

% table options label
cx = col(1);
ctrlPos.tableLabel  = [cx cy tableLabelSize];

% table options edit field
cx = cx + tableLabelSize(1) + colDelta/3;
dx = ctrlPos.descEdit(3) - (cx - ctrlPos.descEdit(1));
ctrlPos.tableEdit  = [cx cy dx  ctrlPos.descEdit(4)];

% increase sheet dimensions
sheetDims(2) = sheetDims(2) ...
    + ctrlPos.addoptGroupbox(4) ...
    + commonGeom.textHeight;


%-----------------------------------------------------------------------------------------
% FcnCreateColumnControls creates Column controls page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateColumnControls(pageNum, dlgfig, dlgdata)

% invoke standard function to create scaling controls
dlgdata = TLManageVariableCtrls('create', pageNum, dlgfig, dlgdata);
dlgdata = TLManageScalingCtrls('create', pageNum, dlgfig, dlgdata);

Children = dlgdata.pageData{pageNum}.children;
ctrlPos = dlgdata.pageData{pageNum}.ctrlPos;
pageName = dlgdata.pageNames{pageNum};

cEditLabeltext = 'Axis#2 (column):';
cEditLabelPos  = ctrlPos.tableLabel;
cEditPos   = ctrlPos.tableEdit;

% create the addoptGroupbox which will contain table values
Children.addoptGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Axis values'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.addoptGroupbox);

Children.cEditLabel = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'Style',              'text', ...
    'String',             cEditLabeltext, ...
    'Position',           cEditLabelPos);

Children.cEdit = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           cEditPos, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''cEdit'')',pageName));

Children.useDDValueCheckbox = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'Style',              'checkbox', ...
    'String',             'Use value of Data Dictionary variable', ...
    'Position',           ctrlPos.useDDValueCheckbox, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''useDDValueCheckbox'')',pageName));

dlgdata.pageData{pageNum}.children = Children;


%-----------------------------------------------------------------------------------------
% FcnManageColumnControls manages Column page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata,bModified] = FcnManageColumnControls(pageNum, dlgfig, dlgdata, pageAction)

bRefreshTool = 0;
Children = dlgdata.pageData{pageNum}.children;

switch pageAction
    
    case 'cEdit'
        cStr = deblank(get(Children.cEdit, 'String'));
        if ~isempty(cStr)
            if strcmp(cStr, 'ddv')
                if isempty(dlgdata.data.col.variable)
                    beep;
                else
                    dlgdata.data.col.value = ['ddv(''', dlgdata.data.col.variable, ''')'];
                    dlgdata.data.col.useddvariablevalue = true;
                end
            else
                dlgdata.data.col.value = cStr;
            end
            bRefreshTool = true;
        else
            beep;
        end
        bModified = true;
        
    case 'useDDValueCheckbox'
        if get(Children.useDDValueCheckbox, 'Value')
            dlgdata.data.col.value = ['ddv(''', dlgdata.data.col.variable, ''')'];
            dlgdata.data.col.useddvariablevalue = true;
        else
            dlgdata.data.col.useddvariablevalue = false;
        end
        bModified = true;
        bRefreshTool = true;
        
    otherwise
        [dlgdata, bModified1] = ...
            TLManageVariableCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'col');
        [dlgdata, bModified2] = ...
            TLManageScalingCtrls('manage', pageNum, dlgfig, dlgdata, pageAction, 'col');
        
        bModified = bModified1 | bModified2;
        bRefreshTool = bModified;
end

dlgdata.bRefreshTool = bRefreshTool;


%--------------------------------------------------------------------------
% FcnUpdateColumnControls updates the controls of the Column tab
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateColumnControls(pageNum, dlgfig, dlgdata)

Children = dlgdata.pageData{pageNum}.children;
dlgdata = TLManageVariableCtrls('update', pageNum, dlgdata, 'col');
data = dlgdata.data;
% get minima and maxima of axis data
[c, cmin, cmax, bCompliant] = tl_eval_table(dlgdata.data.col, true);

constraint = [];
if bCompliant
    constraint = [cmin cmax];
end
dlgdata = TLManageScalingCtrls('update', pageNum, dlgdata, 'col', constraint);

% table value cannot be edited if a look-up table object specifies all
% block data
bWritable = dlgdata.pageData{pageNum}.bWritable.value && ~dlgdata.data.col.useddvariablevalue;
cEditCtrlStatus = struct('enable', FcnbEnabled(bWritable, 1));
cEditCtrlStatus.string = data.col.value;
cEditCtrlStatus.iserror = ~bCompliant;

% status of ddv checkbox
bWritable = dlgdata.pageData{pageNum}.bWritable.value && ~isempty(dlgdata.data.col.variable);
useDDValueCheckboxCtrlStatus.enable = flag2str(bWritable);
useDDValueCheckboxCtrlStatus.value = dlgdata.data.col.useddvariablevalue;

% read scaling controls' UserData
simulatedLabelCtrlStatus = tl_get_control_userdata(Children.simulatedLabel);
upperSimulatedValueCtrlStatus = tl_get_control_userdata(Children.upperSimulatedValue);
lowerSimulatedValueCtrlStatus = tl_get_control_userdata(Children.lowerSimulatedValue);

if ~isempty(c) && bCompliant
    minstr = sprintf('%0.5g', cmin);
    maxstr = sprintf('%0.5g', cmax);
else
    minstr = 'n.a.';
    maxstr = 'n.a.';
end

simulatedLabelCtrlStatus.string = 'of vector';
upperSimulatedValueCtrlStatus.string = maxstr;
lowerSimulatedValueCtrlStatus.string = minstr;

ctrlsList = { ...
    'cEdit' ...
    'simulatedLabel' ...
    'upperSimulatedValue' ...
    'lowerSimulatedValue' ...
    'useDDValueCheckbox'};
for ctrlsNo = 1:numel(ctrlsList)
    ctrl = Children.(ctrlsList{ctrlsNo});
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end

% set control status of variable, scaling and table parameter groupbox controls
TLManageVariableCtrls('setCtrls', pageNum, dlgfig, dlgdata);
TLManageScalingCtrls('setCtrls', pageNum, dlgfig, dlgdata);
TLSetCtrlsStatus(dlgfig, Children, {'cEdit', 'useDDValueCheckbox'})


%-----------------------------------------------------------------------------------------
% FcnCreateDocumentationControls creates documentation page (necessary here
% since for look-up tables, the Documentation page has some extra controls)
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateDocumentationControls(pageNum, dlgfig, dlgdata)

% invoke generic function to create documentation page
dlgdata = TLManageDocCtrls('create', pageNum, dlgfig, dlgdata);

% create additional controls
Children = dlgdata.pageData{pageNum}.children;
ctrlPos = dlgdata.pageData{pageNum}.ctrlPos;
pageName = dlgdata.pageNames{pageNum};
Children.tblFcnName   = uicontrol( ...
    'Parent',            dlgfig, ...
    'Style',             'text', ...
    'String',            'Table function name: n.a.', ...
    'Position',          ctrlPos.tblFcnName);
Children.clipboardButton = uicontrol( ...
    'Parent',            dlgfig, ...
    'Style',             'pushbutton', ...
    'String',            'Copy to Clipboard', ...
    'Position',          ctrlPos.clipboardButton, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''clipboardButton'')',pageName));

% save extended children handle structure
dlgdata.pageData{pageNum}.children = Children;


%-----------------------------------------------------------------------------------------
% FcnManageDocumentationControls manages documentation page (necessary here
% since for look-up tables, the Documentation page has some extra controls)
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata,bModified] = FcnManageDocumentationControls(pageNum, dlgfig, dlgdata, pageAction)

% default return value
bModified = false;

% clipboard callbacks are handled directly here
if strcmp(pageAction, 'clipboardButton')
    clipboard('copy', dlgdata.pageData{pageNum}.tblFcnName);
    return
end

% invoke generic function to manage control callbacks
[dlgdata, bModified] = TLManageDocCtrls('callback', pageNum, dlgfig, ...
    dlgdata,pageAction);


%-----------------------------------------------------------------------------------------
% FcnUpdateDocumentationControls updates documentation page (necessary here
% since for look-up tables, the Documentation page has some extra controls)
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnUpdateDocumentationControls(pageNum, dlgfig, dlgdata)

TLManageDocCtrls('update', pageNum, dlgfig, dlgdata);

% get table data
r = tl_eval_table(dlgdata.data.row, true);
c = tl_eval_table(dlgdata.data.col, true);
t = tl_eval_table(dlgdata.data.table, false, true);

tblFcnName = 'n.a.';

if ~isempty(r) && ~isempty(c) && ~isempty(t)
    % invoke get_2dtabledata in batch mode
    b = ds_error_get('batchmode');
    ds_error_set('batchmode', 'on');
    [tableData,msgstruct] = get_2dtabledata(dlgdata.data,r,c,t,0,inf);
    ds_error_set('batchmode', b);
    
    % determine tablefunction name
    if isempty(msgstruct) || ~any(strcmp({msgstruct.type}, 'Error'))
        tblFcnName = tl_get_tblfcnnames(dlgdata.data, dlgdata.model, ...
            tableData, dlgdata.maskType);
    end
    if iscell(tblFcnName)
        tblFcnName = [tblFcnName{:}];
    end
end

tblFcnNameCtrlStatus = struct('enable', 'on');
clipboardButtonCtrlStatus = struct('enable', 'on');

tblFcnNameCtrlStatus.string = ...
    sprintf('Table function name: %s', tblFcnName);
clipboardButtonCtrlStatus.enable = flag2str(~isempty(tblFcnName) ...
    && ~strcmp(tblFcnName, 'n.a.'));

dlgdata.pageData{pageNum}.tblFcnName = tblFcnName;

ctrlsList = {'tblFcnName', 'clipboardButton'};
Children = dlgdata.pageData{pageNum}.children;
for ctrlsNo = 1:length(ctrlsList)
    ctrl = Children.(ctrlsList{ctrlsNo});
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end

TLSetCtrlsStatus(dlgfig, Children, ctrlsList);


%-----------------------------------------------------------------------------------------
% FcnManageEquidistantSpacing manages the controls that become only enabled
% after equidistant spacing is selected.
%
% INPUT ARGUMENTS
%   datafield       complete data struct of current variable
%   bIntegerType    flag is true on interger type
%
% OUTPUT ARGUMENTS
%   datafield       modified data struct of current variable
%   x0str           string of x0
%   xnstr           string of xn
%   ndiststr        string of integer distance
%   diststr         string of real distance
%   bEquidistant    flag, whether distance should be equiditant
%-----------------------------------------------------------------------------------------
function [datafield, x0str, xnstr, ndiststr, diststr, bEquidistant] = ...
    FcnManageEquidistantSpacing(datafield, bIntegerType)

x0str = '';
xnstr = '';
ndiststr = '';
diststr = '';
bEquidistant = datafield.search==5;

if bEquidistant
    if datafield.arbdistance == 0 && bIntegerType
        ndist = datafield.distance/datafield.lsb;
        datafield.distance = datafield.lsb * 2^(ceil(log2(ndist)));
    end
    
    if ~isempty(datafield.x0) && ~isempty(datafield.xn) ...
            && datafield.x0 == datafield.xn
        datafield.x0 = [];
        datafield.xn = [];
    end
    if bIntegerType
        ndist = round(datafield.distance / datafield.lsb);
        if ndist < 1
            ndist = 1;
        end
        [maxint, minint] = tl_int_bounds(datafield.type);
        if ndist > maxint - minint
            ndist = maxint - minint;
        end
        if datafield.arbdistance == 0
            log2ndist = round(log2(ndist));
            ndist = 2^log2ndist;
            diststr = ['= 2^' num2str(log2ndist) ' x LSB'];
        else
            diststr = ['= ' num2str(ndist) ' x LSB'];
        end
        datafield.distance = ndist * datafield.lsb;
        if ~isempty(datafield.x0)
            datafield.x0 = ...
                datafield.lsb * round((datafield.x0 - datafield.offset) ...
                / datafield.lsb) + datafield.offset;
            x0str = sprintf('%0.7g', datafield.x0);
        end
        if ~isempty(datafield.xn)
            datafield.xn = ...
                datafield.lsb * round((datafield.xn - datafield.offset) ...
                / datafield.lsb) + datafield.offset;
            xnstr = sprintf('%0.7g', datafield.xn);
        end
    else
        if ~isempty(datafield.x0)
            x0str = sprintf('%0.7g', datafield.x0);
        end
        if ~isempty(datafield.xn)
            xnstr = sprintf('%0.7g', datafield.xn);
        end
    end
    ndiststr = sprintf('%0.7g', datafield.distance);
end

%-----------------------------------------------------------------------------------------
% FcnbEnabled to get status for control
%
% INPUT ARGUMENTS
%   bWritable       is control write able
%   defaultStatus   is full version
%
% OUTPUT ARGUMENTS
%   enableStatus    status is 'on' or 'inactive'
%-----------------------------------------------------------------------------------------
function enableStatus = FcnbEnabled(bWritable, defaultStatus)

if defaultStatus && bWritable
    enableStatus = 'on';
else
    enableStatus = 'inactive';
end
